package cn.stylefeng.guns.modular.business.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.stylefeng.guns.modular.business.comment.YunHeKey;
import cn.stylefeng.guns.modular.business.entity.SubDic;
import cn.stylefeng.guns.modular.business.entity.TransportInfo;
import cn.stylefeng.guns.modular.business.entity.CanalSecondClassify;
import cn.stylefeng.guns.modular.business.entity.CanalThreeClassify;
import cn.stylefeng.guns.modular.business.enums.TransportInfoExceptionEnum;
import cn.stylefeng.guns.modular.business.mapper.TransportInfoMapper;
import cn.stylefeng.guns.modular.business.pojo.TransportInfoRequest;
import cn.stylefeng.guns.modular.business.service.CanalSecondClassifyService;
import cn.stylefeng.guns.modular.business.service.CanalThreeClassifyService;
import cn.stylefeng.guns.modular.business.service.SubUseBrowseService;
import cn.stylefeng.guns.modular.business.service.TransportInfoService;
import cn.stylefeng.roses.kernel.auth.api.LoginUserApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 漕运航运业务实现层
 *
 * @author zhangyaowen
 * @date 2021/10/28 16:51
 */
@Service
public class TransportInfoServiceImpl extends ServiceImpl<TransportInfoMapper, TransportInfo> implements TransportInfoService {

    @Resource
    private CanalSecondClassifyService canalSecondClassifyService;
    @Resource
    private CanalThreeClassifyService canalThreeClassifyService;
    @Resource
    private LoginUserApi loginUserApi;
    @Resource
    private SubUseBrowseService subUseBrowseService;


    @Override
    public void add(TransportInfoRequest transportInfoRequest) {
        TransportInfo transportInfo = new TransportInfo();
        BeanUtil.copyProperties(transportInfoRequest, transportInfo);
        this.save(transportInfo);
    }

    @Override
    public void del(TransportInfoRequest transportInfoRequest) {
        TransportInfo transportInfo = this.queryTransportInfo(transportInfoRequest);
        this.removeById(transportInfo.getId());
    }

    @Override
    public void edit(TransportInfoRequest transportInfoRequest) {
        TransportInfo transportInfo = this.queryTransportInfo(transportInfoRequest);
        BeanUtil.copyProperties(transportInfoRequest, transportInfo);
        this.updateById(transportInfo);
    }

    @Override
    public TransportInfo detail(TransportInfoRequest transportInfoRequest) {
        return this.queryTransportInfo(transportInfoRequest);
    }

    @Override
    public PageResult<Map<String,Object>> findPage(String threeClassifyName ,String secondClassifyName) {
        TransportInfoRequest transportInfoRequest = new TransportInfoRequest();
        transportInfoRequest.setTraSecond(secondClassifyName);
        transportInfoRequest.setTraThird(threeClassifyName);
        LambdaQueryWrapper<TransportInfo> wrapper = createWrapperByPage(transportInfoRequest);
        Page<TransportInfo> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        PageResult<TransportInfo> TransportInfoPageResult = PageResultFactory.createPageResult(sysRolePage);
        List<TransportInfo> transportInfoList=TransportInfoPageResult.getRows();
        List<Map<String,Object>> mapList=new ArrayList<>();
        PageResult<Map<String,Object>> pageResult = new PageResult<>();
        for(TransportInfo transportInfo:transportInfoList){
            Map<String, Object> map = new HashMap<String, Object>();
            byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
            SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

            String jmid = YunHeKey.CYHY+transportInfo.getId();
            String encryptHex = aes.encryptHex(jmid);
            map.put("id",encryptHex);
            map.put("title",transportInfo.getTraTitle());
            map.put("traThird",transportInfo.getTraThird());
            map.put("annalsfrom",transportInfo.getTraAnnalsfrom());
            mapList.add(map);

        }
        pageResult.setRows(mapList);
        pageResult.setPageSize(TransportInfoPageResult.getPageSize());
        pageResult.setPageNo(TransportInfoPageResult.getPageNo());
        pageResult.setTotalPage(TransportInfoPageResult.getTotalPage());
        pageResult.setTotalRows(TransportInfoPageResult.getTotalRows());
        return pageResult;
    }

    @Override
    public List<TransportInfo> findList(TransportInfoRequest transportInfoRequest) {
        LambdaQueryWrapper<TransportInfo> wrapper = this.createWrapper(transportInfoRequest);
        return this.list(wrapper);
    }

    /**
     * 获取信息
     *
     * @author zhangyaowen
     * @date 2021/10/28 16:51
     */
    private TransportInfo queryTransportInfo(TransportInfoRequest transportInfoRequest) {
        TransportInfo transportInfo = this.getById(transportInfoRequest.getId());
        if (ObjectUtil.isEmpty(transportInfo)) {
            throw new ServiceException(TransportInfoExceptionEnum.TRANSPORTINFO_NOT_EXISTED);
        }
        return transportInfo;
    }

    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/10/28 16:51
     */
    private LambdaQueryWrapper<TransportInfo> createWrapper(TransportInfoRequest transportInfoRequest) {
        LambdaQueryWrapper<TransportInfo> queryWrapper = new LambdaQueryWrapper<>();

        Long id = transportInfoRequest.getId();
        String traFirst = transportInfoRequest.getTraFirst();
        String traSecond = transportInfoRequest.getTraSecond();
        String traThird = transportInfoRequest.getTraThird();
        String traFourth = transportInfoRequest.getTraFourth();
        String traFifth = transportInfoRequest.getTraFifth();
        String traHistory = transportInfoRequest.getTraHistory();
        String historyDating = transportInfoRequest.getHistoryDating();
        String theCommon = transportInfoRequest.getTheCommon();
        String traIntroduce = transportInfoRequest.getTraIntroduce();
        String traAnnotation = transportInfoRequest.getTraAnnotation();
        String traAnnalsfrom = transportInfoRequest.getTraAnnalsfrom();
        String traAnnalspage = transportInfoRequest.getTraAnnalspage();

        queryWrapper.eq(ObjectUtil.isNotNull(id), TransportInfo::getId, id);
        queryWrapper.like(ObjectUtil.isNotEmpty(traFirst), TransportInfo::getTraFirst, traFirst);
        queryWrapper.like(ObjectUtil.isNotEmpty(traSecond), TransportInfo::getTraSecond, traSecond);
        queryWrapper.like(ObjectUtil.isNotEmpty(traThird), TransportInfo::getTraThird, traThird);
        queryWrapper.like(ObjectUtil.isNotEmpty(traFourth), TransportInfo::getTraFourth, traFourth);
        queryWrapper.like(ObjectUtil.isNotEmpty(traFifth), TransportInfo::getTraFifth, traFifth);
        queryWrapper.like(ObjectUtil.isNotEmpty(traHistory), TransportInfo::getTraHistory, traHistory);
        queryWrapper.like(ObjectUtil.isNotEmpty(historyDating), TransportInfo::getHistoryDating, historyDating);
        queryWrapper.like(ObjectUtil.isNotEmpty(theCommon), TransportInfo::getTheCommon, theCommon);
        queryWrapper.like(ObjectUtil.isNotEmpty(traIntroduce), TransportInfo::getTraIntroduce, traIntroduce);
        queryWrapper.like(ObjectUtil.isNotEmpty(traAnnotation), TransportInfo::getTraAnnotation, traAnnotation);
        queryWrapper.like(ObjectUtil.isNotEmpty(traAnnalsfrom), TransportInfo::getTraAnnalsfrom, traAnnalsfrom);
        queryWrapper.like(ObjectUtil.isNotEmpty(traAnnalspage), TransportInfo::getTraAnnalspage, traAnnalspage);

        return queryWrapper;
    }

    private LambdaQueryWrapper<TransportInfo> createWrapperByPage(TransportInfoRequest transportInfoRequest) {
        LambdaQueryWrapper<TransportInfo> queryWrapper = new LambdaQueryWrapper<>();
        
        String traSecond = transportInfoRequest.getTraSecond();
        String traThird = transportInfoRequest.getTraThird();
        queryWrapper.eq(ObjectUtil.isNotEmpty(traSecond), TransportInfo::getTraSecond, traSecond);
        queryWrapper.eq(ObjectUtil.isNotEmpty(traThird), TransportInfo::getTraThird, traThird);

        return queryWrapper;
    }

    @Override
    public List<Map<String,Object>> findTran() {
        CanalSecondClassify canalSecondClassfiy = new CanalSecondClassify();
        canalSecondClassfiy.setCanalFirstClassifyCode(YunHeKey.CYHY);
        List<Map<String,Object>> mapList = new ArrayList<>();
        List<Map<String,Object>> SecondClassify =  canalSecondClassifyService.findSecondList(canalSecondClassfiy);
        for(Map<String,Object> map : SecondClassify){
            CanalThreeClassify canalThreeClassify = new CanalThreeClassify();
            Map<String, Object> map1 = new HashMap<String, Object>();
            map1.put("secondClassifyName",map.get("canalSecondClassifyName"));
            canalThreeClassify.setCanalSecondClassifyCode( map.get("canalSecondClassifyCode").toString());
            List< Map<String, Object>> ThreeClassifyList = new ArrayList<>();
            List<CanalThreeClassify> ThreeClassify =  canalThreeClassifyService.findThreeList(canalThreeClassify);
            for(CanalThreeClassify canalThreeClassify1 : ThreeClassify){
                Map<String, Object> mapThree = new HashMap<String, Object>();
                mapThree.put("threeClassifyName",canalThreeClassify1.getCanalThreeClassifyName());
                mapThree.put("threeClassifyCode",canalThreeClassify1.getCanalThreeClassifyCode());
                mapThree.put("secondClassifyCode",canalThreeClassify1.getCanalSecondClassifyCode());
                mapThree.put("firstClassifyCode",canalThreeClassify1.getCanalFirstClassifyCode());
                ThreeClassifyList.add(mapThree);
            }
            map1.put("list",ThreeClassifyList);
            mapList.add(map1);
        }
        return mapList;
    }

    @Override
    public Map<String, Object> toReview(String jmId) {
        byte[] key =YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
        String decryptStr = aes.decryptStr(jmId, CharsetUtil.CHARSET_UTF_8);
        //获取ID字符串YHSJ后面真实的的id
        String id = StrUtil.subAfter(decryptStr,YunHeKey.CYHY,false);
        HttpServletRequest request = HttpServletUtil.getRequest();
        Long userid;
        if (ObjectUtil.isNotNull(request)) {

            LoginUser loginUser = loginUserApi.getLoginUser();
            userid = loginUser.getUserId();
        } else {
            throw new ServiceException(TransportInfoExceptionEnum.REQUEST_EMPTY);
        }
        LambdaQueryWrapper<TransportInfo> queryWrapper = new LambdaQueryWrapper<>();
        if ("".equals(id)) {
            Map<String, Object> mapLists = new HashMap<>();
            return mapLists;
        }
        queryWrapper.eq(ObjectUtil.isNotEmpty(id), TransportInfo::getId, id);
        List<TransportInfo> TransportInfoList = this.list(queryWrapper);


        List<Map<String, Object>> mapList = new ArrayList<>();
        for (TransportInfo transportInfo : TransportInfoList) {

            Map<String, Object> map = new HashMap<String, Object>();
            map = JSONObject.parseObject(JSONObject.toJSONString(transportInfo), Map.class);

            // 获取类的属性
            Field[] declaredFields = TransportInfo.class.getDeclaredFields();
            List<Map<String, Object>> mplist = new ArrayList<>();
            // 遍历属性，获取属性上ApiModelProperty的值，属性的名，存入Properties
            if (declaredFields.length != 0) {
//                String title = "";
                int i = 1;
                Map<String, Object> p = new HashMap<String, Object>();
                for (Field field : declaredFields) {

                    Map<String, Object> mp = new HashMap<String, Object>();
                    if (field.getAnnotation(ApiModelProperty.class) != null) {
                        //获取注解属性
                        ApiModelProperty aa = field.getAnnotation(ApiModelProperty.class);
                        // key和value可根据需求存
                        // 这存的key为注解的值，value为类属性名

                        if ("traIntroduce".equals(field.getName()) || "traAnnotation".equals(field.getName()) ||"traTitle".equals(field.getName()) ) {
                            if ("traTitle".equals(field.getName()) ) {
                                p.put("title", map.get(field.getName()));
                            }else if("traAnnotation".equals(field.getName())){
                                p.put("annotation", map.get(field.getName()));
                            }
                            else {
                                p.put(field.getName(), map.get(field.getName()));
                            }
                        }else{
                            mp.put("key", aa.value());
                            mp.put("value", map.get(field.getName()));
                            if (i != 1) {
                                mplist.add(mp);
                            }
                        }
                    }
                    i++;
                }
                p.put("list", mplist);
                if (i != 1) {
                    mapList.add(p);
                }
            }
        }
        if(userid != 0l && userid != -1l) {
            subUseBrowseService.saveBrowse(YunHeKey.YHCYHY,mapList.get(0).get("title").toString(),userid,request);
        }
        return mapList.get(0);
    }

    @Override
    public List<Map<String,Object>> findAllList(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<TransportInfo> wrapper = createWrappers(riverList,townList,times,name);
        List<TransportInfo>  list = this.list(wrapper);
        List<Map<String,Object>> mapList=new ArrayList<>();
        for(TransportInfo transportInfo:list) {
            Map<String, Object> map = new HashMap<String, Object>();
//            Map<String, Object> map1 = new HashMap<String, Object>();
//            map = JSONObject.parseObject(JSONObject.toJSONString(eventsInfo), Map.class);

            map.put("title", transportInfo.getTraTitle());
            map.put("historyDating",transportInfo.getHistoryDating());
            map.put("theCommon",transportInfo.getTheCommon());
            map.put("from",transportInfo.getTraAnnalsfrom() );
            map.put("createTime",DateUtil.format(transportInfo.getCreateTime(), "yyyy-MM-dd"));
            map.put("type",YunHeKey.CYHY);
            byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
            SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

            String jmid = YunHeKey.CYHY+transportInfo.getId();
            String encryptHex = aes.encryptHex(jmid);
            map.put("id",encryptHex);
            mapList.add(map);
        }
        return mapList;
    }
    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/08/30 10:17
     */
    private LambdaQueryWrapper<TransportInfo> createWrappers(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<TransportInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.and(i-> i.like(ObjectUtil.isNotNull(name), TransportInfo::getTraTitle, name).or()
                .like(ObjectUtil.isNotNull(name), TransportInfo::getHistoryDating, name).or()
                .like(ObjectUtil.isNotNull(name), TransportInfo::getTheCommon, name).or()
                .like(ObjectUtil.isNotNull(name), TransportInfo::getTraAnnalsfrom, name));
        if( !riverList.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < riverList.size(); i++) {
                    String dicAname = riverList.get(i).getDicAname();
                    wrapper.like(ObjectUtil.isNotEmpty(dicAname), TransportInfo::getXgRiver, dicAname);
                    if (i != riverList.size() - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        if( times.length !=0) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < times.length; i++) {
                    String time = times[i];
                    wrapper.like(ObjectUtil.isNotEmpty(time), TransportInfo::getTraHistory, time)
                            .or();
                    wrapper.like(ObjectUtil.isNotEmpty(time), TransportInfo::getHistoryDating, time)
                            .or();
                    wrapper.like(ObjectUtil.isNotEmpty(time), TransportInfo::getTheCommon, time);
                    if (i != times.length - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        for(int i=0 ;i<townList.size();i++) {
            String dicZname = townList.get(i).getDicZname();
            queryWrapper.like(ObjectUtil.isNotEmpty(dicZname), TransportInfo::getXgTown, dicZname);
            if(i !=townList.size()-1) {
                queryWrapper.or();
            }
        }
//        for(int i=0 ;i<times.length;i++) {
//            String time = times[i];
//            queryWrapper.like(ObjectUtil.isNotEmpty(time), EventsInfo::getEventsSecond, time);
//            if(i !=times.length-1) {
//                queryWrapper.or();
//            }
//        }
        return queryWrapper;
    }
}